home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / progtool / modula2 / hk_lib / def_mod / memory.mod < prev    next >
Encoding:
Modula Implementation  |  1994-09-22  |  16.4 KB  |  401 lines

  1. IMPLEMENTATION MODULE  MEMORY;
  2.  
  3. (*****************************************************************************)
  4. (* Da das Programmieren dieser hardwarenahen Funktionen in MODULA zu vielen  *)
  5. (* unschoenen Verrenkungen gefuehrt haette, wurden sie gleich alle in ASSEM- *)
  6. (* BLER programmiert.                                                        *)
  7. (*                                                                           *)
  8. (* Allgemeine Vorgehensweise:                                                *)
  9. (* ------------------------------------------------------------------------- *)
  10. (* Sind die Startadressen der Speicherbereiche ungerade, wird ein Byte vorne-*)
  11. (* weg geschrieben und die Anzahl um eins verringert; danach wird die Anzahl *)
  12. (* der Bytes in die Anzahl der entsprechenden Langworte umgerechnet, damit   *)
  13. (* das Kopieren moeglichst schnell geht. Aus einer ungeraden Startadresse    *)
  14. (* und/oder einer ungeraden Anzahl kann es sich ergeben, dass zum Schluss    *)
  15. (* ein einzelnes Wort und/oder Byte geschrieben werden muessen.              *)
  16. (*                                                                           *)
  17. (* Beim Kopieren von Speicherbereichen muss noch darauf geachtet werden, dass*)
  18. (* mit dem ENDE des Speicherbereichs begonnen wird, falls der Zielbereich    *)
  19. (* ueberlappend HINTER dem Quellbereich liegt; liegt der Zielbereich hinge-  *)
  20. (* gen ueberlappend VOR dem Quellbereich, muss mit dem ANFANG des Quellbe-   *)
  21. (* reichs begonnen werden. ( Haelt man sich nicht an diese Regeln, wird der  *)
  22. (* Quellbereich waehrend des Kopierens ueberschrieben ).                     *)
  23. (*___________________________________________________________________________*)
  24. (*                                                                           *)
  25. (* Oktober '89                                                               *)
  26. (*       Beginn auf dem Papier                                               *)
  27. (* 23-Nov-89 , hk                                                            *)
  28. (*       erste Version                                                       *)
  29. (* 31-Dez-89 , hk                                                            *)
  30. (*       "CopySmallMem" fuer kleine Speicherbereiche                         *)
  31. (* 07-Feb-90 , hk                                                            *)
  32. (*       Typ "CopyProc"                                                      *)
  33. (*****************************************************************************)
  34.  
  35. FROM  SYSTEM  IMPORT (* TYPE *)  ADDRESS,
  36.                      (* PROC *)  INLINE;
  37.  
  38. (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
  39.  
  40.  
  41. PROCEDURE  ClearMem ((* EIN/ -- *)  start  : ADDRESS;
  42.                      (* EIN/ -- *)  laenge : CARDINAL );
  43. (*T*)
  44.    BEGIN
  45. (*
  46.    laenge  EQU  12
  47.    start   EQU  laenge + 2
  48.  
  49.    ClearMem:
  50.      move.w  laenge(a6), d0  ; Anzahl zu loeschender Bytes
  51.      beq.s   ende            ; B: nichts zu loeschen
  52.      movea.l start(a6), a0   ; a0 -> Startadresse
  53.      move.l  a0, d2          ; fuer Bittest noetig
  54.      moveq   #0, d1          ; statt clr.X fuer schnelles Loeschen
  55.      btst    #0, d2          ; Startadresse ungerade ?
  56.      beq.s   wordcnt         ; B: nein
  57.      move.b  d1, (a0)+       ; sonst das erste Byte loeschen -> gerade Adr.
  58.      subq.w  #1, d0          ; ein Byte weniger zu loeschen
  59.    wordcnt:
  60.      move.w  d0, d2          ; Anzahl fuer spaeteren Ueberhangtest
  61.      lsr.w   #2, d0          ; Anzahl zu loeschender Langworte
  62.      bra.s   clrlp + 2       ; langwortweise loeschen
  63.    clrlp:                    ;
  64.      move.l  d1, (a0)+       ;
  65.      dbra    d0, clrlp       ;
  66.      btst    #1, d2          ; erst auf zusaetzliches Wort statt Byte testen,
  67.                              ; damit gerade Adresse
  68.      beq.s   tstbyte         ; B: kein zusaetzliches Wort
  69.      move.w  d1, (a0)+       ; ein Wort loeschen
  70.    tstbyte:
  71.      btst    #0, d2          ; noch ein letztes Byte ?
  72.      beq.s   ende            ; B: nein
  73.      move.b  d1, (a0)        ; der letzte Rest, jetzt ist ung. Adr., egal
  74.    ende:
  75. *)
  76.    INLINE( 302EH,000CH,672EH,206EH,000EH,2408H,7200H,0802H,0000H );
  77.    INLINE( 6704H,10C1H,5340H,3400H,0E448H,6002H,20C1H,51C8H,0FFFCH );
  78.    INLINE( 0802H,0001H,6702H,30C1H,0802H,0000H,6702H,1081H );
  79.  
  80.    END  ClearMem;
  81.  
  82. (*---------------------------------------------------------------------------*)
  83.  
  84. PROCEDURE  FillMem ((* EIN/ -- *)  start  : ADDRESS;
  85.                     (* EIN/ -- *)  laenge : CARDINAL;
  86.                     (* EIN/ -- *)  muster : LONGCARD );
  87. (*T*)
  88.    BEGIN
  89. (*
  90.    muster  EQU  12
  91.    laenge  EQU  muster + 4
  92.    start   EQU  laenge + 2
  93.  
  94.    FillMem:
  95.      move.w  laenge(a6), d0  ; Anzahl zu fuellender Bytes
  96.      beq.s   ende            ; B: nix los
  97.      movea.l start(a6), a0   ; a0 -> Startadresse
  98.      move.l  a0, d2          ; fuer Bittest noetig
  99.      move.l  muster(a6), d1  ; Fuellmuster
  100.      btst    #0, d2          ; ungerade Startadr. ?
  101.      beq.s   wordcnt         ; B: nein
  102.      rol.l   #8, d1          ; es soll ja mit dem hoechstwertigen Byte des
  103.                              ; des Musters begonnen werden, damit gibt es
  104.                              ; auch ein kontinuierliches Muster beginnend
  105.                              ; mit einer ungeraden Adr. ( die drei folgenden
  106.                              ; Bytes ruecken bei dem ROTATE-Befehl entsprechend
  107.                              ; auf, und das erste Byte folgt wieder dahinter
  108.      move.b  d1, (a0)+       ;
  109.      subq.w  #1, d0          ; ein Byte weniger zu fuellen
  110.    wordcnt:
  111.      move.w  d0, d2          ; fuer spaeteren Ueberhangtest
  112.      lsr.w   #2, d0          ; Anzahl zu fuellender Langworte
  113.      bra.s   fillp + 2       ; Speicherbereich langwortweise beschreiben
  114.    fillp:
  115.      move.l  d1, (a0)+       ;
  116.      dbra    d0, fillp       ;
  117.      btst    #1, d2          ; noch ein zusaetzliches Wort ?
  118.      beq.s   tstbyte         ; B: nein
  119.      swap    d1              ; damit werden zwei Byte des Musters von links
  120.      move.w  d1, (a0)+       ; zusaetzlich geschrieben
  121.    tstbyte:
  122.      btst    #0, d2          ; noch ein zusaetzliches Byte ?
  123.      beq.s   ende            ; B: nein
  124.      rol.l   #8, d1          ; damit ist das auf das letzte bisher geschriebene
  125.                              ; Byte des Musters folgende im unteren Byte des
  126.                              ; Registers
  127.      move.b  d1, (a0)        ;
  128.    ende:
  129. *)
  130.    INLINE( 302EH,0010H,6736H,206EH,0012H,2408H,222EH,000CH,0802H );
  131.    INLINE( 0000H,6706H,0E199H,10C1H,5340H,3400H,0E448H,6002H,20C1H );
  132.    INLINE( 51C8H,0FFFCH,0802H,0001H,6704H,4841H,30C1H,0802H,0000H );
  133.    INLINE( 6704H,0E199H,1081H );
  134.  
  135.    END  FillMem;
  136.  
  137. (*---------------------------------------------------------------------------*)
  138.  
  139. PROCEDURE  CopyMem ((* EIN/ -- *)  quelle,
  140.                     (* EIN/ -- *)  ziel   : ADDRESS;
  141.                     (* EIN/ -- *)  laenge : CARDINAL );
  142. (*T*)
  143.    BEGIN
  144. (*
  145.    laenge  EQU  12
  146.    ziel    EQU  laenge + 2
  147.    quelle  EQU  ziel + 4
  148.  
  149.    CopyMem:
  150.      move.w  laenge(a6),d0   ; Anzahl der Bytes
  151.      beq     ende            ; nix zu kopieren
  152.      movea.l quelle(a6),a0   ; a0 -> quelle
  153.      movea.l ziel(a6),a1     ; a1 -> ziel
  154.      cmpa.l  a0, a1          ; Quelle vor Ziel ?
  155.      shi     d3              ; B: ja merken ( d3 # 0  <=> von hinten mit
  156.                              ; Predekrement -(ax) kopieren )
  157.      bls.s   tstalgn         ; B: nein, kann mit Postinkr. kopiert werden
  158.      adda.w  d0,a0           ; sonst von hinten mit Predekr. kopieren
  159.      adda.w  d0,a1           ; a0, a1 -> eins hinter letztem Byte
  160.    tstalgn:
  161.      move.l  a0,d1
  162.      move.l  a1,d2
  163.      eor.b   d2,d1           ; genau eine Adr. ungerade ?
  164.      btst    #0,d1           ;
  165.      beq.s   fastcp          ; B: nein, beide gerade/ungerade -> schnell kop.
  166.      tst.b   d3              ; welche Richtung kopieren ?
  167.      bne.s   slspcp+2        ; B: von hinten
  168.      bra.s   slnrmcp+2       ; B: sonst von vorne
  169.    slnrmcp:
  170.      move.b  (a0)+,(a1)+
  171.      dbra    d0,slnrmcp
  172.      bra     ende            ; fertig
  173.  
  174.    slspcp:
  175.      move.b  -(a0),-(a1)     ; alles byteweise von hinten nach vorne kopieren
  176.      dbra    d0,slspcp       ;
  177.      bra     ende            ; fertig
  178.  
  179.    fastcp:
  180.      btst    #0,d2           ; beide Adr. gerade oder beide ungerade ?
  181.      beq.s   longcnt         ; B: beide gerade, kein Byte vorneweg
  182.      tst.b   d3              ; welche Richtung ?
  183.      bne.s   snglsp          ; B: von hinten
  184.      move.b  (a0)+,(a1)+     ; ein Byte -> gerade Adresse
  185.      bra.s   decone
  186.    snglsp:
  187.      move.b  -(a0),-(a1)     ; ein Byte -> gerade Adresse
  188.    decone:
  189.      subq.w  #1,d0           ; ein Byte weniger zu kopieren
  190.    longcnt:
  191.      move.w  d0,d2           ; fuer spaeteren Ueberhangtest
  192.      lsr.w   #2,d0           ; Anzahl zu kopierender Langworte
  193.      tst.b   d3              ; welche Richtung ?
  194.      bne.s   copysp+2        ; B: von hinten alles langwortweise kopieren
  195.      bra.s   copynrm+2       ; B: von vorne
  196.    copynrm:
  197.      move.l  (a0)+,(a1)+
  198.      dbra    d0,copynrm
  199.      btst    #1,d2           ; ein zusaetzliches Wort ?
  200.      beq.s   tstbtnrm        ; B: nein
  201.      move.w  (a0)+,(a1)+     ; ein Wort zusaetzlich
  202.    tstbtnrm:
  203.      btst    #0,d2           ; ein zusaetzliches Byte ?
  204.      beq.s   ende            ; B: nein, fertig
  205.      move.b  (a0)+,(a1)+     ;
  206.      bra.s   ende            ; fertig
  207.  
  208.    copysp:
  209.      move.l  -(a0),-(a1)     ; Schleife und Abfragen wie oben
  210.      dbra    d0,copysp
  211.      btst    #1,d2
  212.      beq.s   tstbtsp
  213.      move.w  -(a0),-(a1)
  214.    tstbtsp:
  215.      btst    #0,d2
  216.      beq.s   ende
  217.      move.b  -(a0),-(a1)
  218.    ende:
  219. *)
  220.    INLINE( 302EH,000CH,6700H,0084H,206EH,0012H,226EH,000EH,0B3C8H );
  221.    INLINE( 52C3H,6304H,0D0C0H,0D2C0H,2208H,2409H,0B501H,0801H,0000H );
  222.    INLINE( 671AH,4A03H,660EH,6002H,12D8H,51C8H,0FFFCH,6000H,0056H );
  223.    INLINE( 1320H,51C8H,0FFFCH,6000H,004CH,0802H,0000H,670CH,4A03H );
  224.    INLINE( 6604H,12D8H,6002H,1320H,5340H,3400H,0E448H,4A03H,661CH );
  225.    INLINE( 6002H,22D8H,51C8H,0FFFCH,0802H,0001H,6702H,32D8H,0802H );
  226.    INLINE( 0000H,671AH,12D8H,6016H,2320H,51C8H,0FFFCH,0802H,0001H );
  227.    INLINE( 6702H,3320H,0802H,0000H,6702H,1320H );
  228.  
  229.    END  CopyMem;
  230.  
  231. (*---------------------------------------------------------------------------*)
  232.  
  233. PROCEDURE  CopySmallMem ((* EIN/ -- *)  quelle,
  234.                          (* EIN/ -- *)  ziel   : ADDRESS;
  235.                          (* EIN/ -- *)  laenge : CARDINAL );
  236. (*T*)
  237.    BEGIN
  238. (*
  239.    laenge  EQU  12
  240.    ziel    EQU  laenge + 2
  241.    quelle  EQU  ziel + 4
  242.  
  243.    CopySmallMem:
  244.      move.w  laenge(a6),d0   ; Anzahl der Bytes
  245.      movea.l quelle(a6),a0   ; a0 -> quelle
  246.      movea.l ziel(a6),a1     ; a1 -> ziel
  247.      bra.s   cpylp + 2       ; byteweise kopieren,ohne Ruecksicht auf Verluste
  248.    cpylp:
  249.      move.b  (a0)+, (a1)+
  250.      dbra    d0, cpylp
  251. *)
  252.    INLINE( 302EH,000CH,206EH,0012H,226EH,000EH,6002H,12D8H,51C8H,0FFFCH );
  253.  
  254.    END  CopySmallMem;
  255.  
  256. (*---------------------------------------------------------------------------*)
  257.  
  258. PROCEDURE  SwapMem ((* EIN/ -- *)  block1,
  259.                     (* EIN/ -- *)  block2 : ADDRESS;
  260.                     (* EIN/ -- *)  laenge : CARDINAL );
  261. (*T*)
  262.    BEGIN
  263. (*
  264.    anzahl  EQU  12
  265.    block2  EQU  anzahl + 2
  266.    block1  EQU  block2 + 4
  267.  
  268.    SwapMem:
  269.      move.w  anzahl(a6), d0  ; Anzahl zu tauschender Bytes
  270.      beq.s   ende            ; B: nichts zu vertauschen
  271.      movea.l block1(a6), a0
  272.      movea.l block2(a6), a1
  273.    tstslow:
  274.      move.l  a0, d1
  275.      move.l  a1, d2
  276.      eor.b   d2, d1          ; genau eine der Adressen ungerade ?
  277.      btst    #0, d1          ;
  278.      beq.s   fastswap        ; B: nein
  279.      bra.s   slowswap + 6    ; sonst die beiden Bloecke byteweise vertauschen
  280.    slowswap:
  281.      move.b  (a0), d1
  282.      move.b  (a1), (a0)+
  283.      move.b  d1, (a1)+
  284.      dbra    d0, slowswap
  285.      bra.s   ende            ; fertig
  286.  
  287.    fastswap:
  288.      btst    #0, d2          ; beide Adr. ungerade oder beide gerade ?
  289.      beq.s   longcnt         ; B: beide gerade
  290.      move.b  (a0), d1        ; sonst ein Byte vorneweg tauschen
  291.      move.b  (a1), (a0)+     ; -> gerade Adresse
  292.      move.b  d1, (a1)+
  293.      subq.w  #1, d0          ; eins weniger zu tauschen
  294.    longcnt:
  295.      move.w  d0, d2          ; fuer spaeteren Ueberhangtest
  296.      lsr.w   #2, d0          ; Anzahl auszutauschender Langworte
  297.      bra.s   swaplp + 6      ; die Bloecke langwortweise vertauschen
  298.    swaplp:
  299.      move.l  (a0), d1
  300.      move.l  (a1), (a0)+
  301.      move.l  d1, (a1)+
  302.      dbra    d0, swaplp
  303.      btst    #1, d2          ; noch ein zusaetzl. Wort auszutauschen ?
  304.      beq.s   tstbtswap       ; B: nein
  305.      move.w  (a0), d1
  306.      move.w  (a1), (a0)+
  307.      move.w  d1, (a1)+
  308.    tstbtswap:
  309.      btst    #0, d2          ; noch ein Byte ?
  310.      beq.s   ende            ; B: nein, fertig
  311.      move.b  (a0), d1
  312.      move.b  (a1), (a0)
  313.      move.b  d1, (a1)
  314.    ende:
  315. *)
  316.    INLINE( 302EH,000CH,6758H,206EH,0012H,226EH,000EH );
  317.    INLINE( 2208H,2409H,0B501H,0801H,0000H,670EH,6006H,1210H );
  318.    INLINE( 10D1H,12C1H,51C8H,0FFF8H,6036H,0802H,0000H,6708H,1210H );
  319.    INLINE( 10D1H,12C1H,5340H,3400H,0E448H,6006H,2210H,20D1H,22C1H );
  320.    INLINE( 51C8H,0FFF8H,0802H,0001H,6706H,3210H,30D1H,32C1H,0802H );
  321.    INLINE( 0000H,6706H,1210H,1091H,1281H );
  322.  
  323.    END  SwapMem;
  324.  
  325. (*---------------------------------------------------------------------------*)
  326.  
  327. PROCEDURE  EqualMem ((* EIN/ -- *)  block1,
  328.                      (* EIN/ -- *)  block2 : ADDRESS;
  329.                      (* EIN/ -- *)  laenge : CARDINAL ): BOOLEAN;
  330. (*T*)
  331.    BEGIN
  332. (*
  333.    anzahl  EQU  12
  334.    block2  EQU  anzahl + 2
  335.    block1  EQU  block2 + 4
  336.    RETURN  EQU  block1 + 4
  337.  
  338.    EqualMem:
  339.      move.w  anzahl(a6), d0  ; Anzahl zu vergl. Bytes
  340.      beq.s   equal           ; B: nichts zu vergleichen
  341.      movea.l block1(a6), a0  ; a0 -> block1
  342.      movea.l block2(a6), a1  ; a1 -> block2
  343.      moveq   #0, d3          ; Default: FALSE
  344.      move.l  a0, d1          ; fuer Bittest
  345.      move.l  a1, d2          ;
  346.      eor.b   d2, d1          ; genau eine Adr. ungerade ?
  347.      btst    #0, d1          ;
  348.      beq.s   fastcmp         ; B: nein, beide gerade/ungerade
  349.      moveq   #0, d7          ; damit beim ersten DBNE-Befehl die Bedingung
  350.                              ; NE nicht erfuellt ist, sonst wird die Schleife
  351.                              ; nie ausgefuehrt und die beiden Speicherbereiche
  352.                              ; werden grundsaetzlich fuer ungleich gehalten !!
  353.      bra.s   slowcmp + 2     ; sonst alles byteweise vergleichen
  354.    slowcmp:
  355.      cmpm.b  (a0)+, (a1)+
  356.      dbne    d0, slowcmp
  357.      bne.s   ende            ; B: ein unterschiedliches Byte gefunden
  358.      bra.s   equal           ; B: Bloecke sind gleich
  359.  
  360.    fastcmp:
  361.      btst    #0, d2          ; beide Adressen ungerade ?
  362.      beq.s   calclw          ; B: nein, beide gerade
  363.      cmpm.b  (a0)+, (a1)+    ; sonst ein Byte vergl. -> gerade Adr.
  364.      bne.s   ende            ; B: schon das erste Byte unterschiedlich
  365.      subq.w  #1, d0          ; sonst ein Byte weniger zu vergleichen
  366.    calclw:
  367.      move.w  d0, d2          ; fuer Ueberhangtest
  368.      lsr.w   #2, d0          ; Anzahl zu vergleichender Langworte
  369.      moveq   #0, d7          ; damit beim ersten DBNE-Befehl die Bedingung
  370.                              ; NE nicht erfuellt ist
  371.      bra.s   longcmp + 2     ; alles langwortweise vergleichen
  372.    longcmp:
  373.      cmpm.l  (a0)+, (a1)+
  374.      dbne    d0, longcmp
  375.      bne.s   ende            ; B: unterschiedliches Byte entdeckt
  376.      btst    #1, d2          ; noch ein abschliessendes Wort vergl. ?
  377.      beq.s   tstbyte         ; B: nein
  378.      cmpm.w  (a0)+, (a1)+    ; letztes Wort auch gleich ?
  379.      bne.s   ende            ; B: nein, Bloecke nicht gleich
  380.    tstbyte:
  381.      btst    #0, d2          ; letztes Byte vergl. ?
  382.      beq.s   equal           ; B: nein, bis hierhin alles gleich
  383.      cmpm.b  (a0)+, (a1)+    ; letztes Byte auch gleich ?
  384.      bne.s   ende            ; B: nein, jetzt hats uns doch noch erwischt
  385.    equal:
  386.      moveq   #1, d3          ; sonst TRUE
  387.    ende:
  388.      move.b  d3, RETURN(a6)
  389. *)
  390.    INLINE( 302EH,000CH,6754H,206EH,0012H,226EH,000EH,7600H,2208H );
  391.    INLINE( 2409H,0B501H,0801H,0000H,670EH,7E00H,6002H,0B308H,56C8H );
  392.    INLINE( 0FFFCH,6634H,6030H,0802H,0000H,6706H,0B308H,6628H,5340H );
  393.    INLINE( 3400H,0E448H,7E00H,6002H,0B388H,56C8H,0FFFCH,6616H,0802H );
  394.    INLINE( 0001H,6704H,0B348H,660CH,0802H,0000H,6704H,0B308H,6602H );
  395.    INLINE( 7601H,1D43H,0016H );
  396.  
  397.    END  EqualMem;
  398.  
  399.  
  400. END  MEMORY.
  401.